package com.ericsson.enap.modules.backup.utils;

import com.jcraft.enipjsch.ChannelShell;
import com.jcraft.enipjsch.JSch;
import com.jcraft.enipjsch.JSchException;
import com.jcraft.enipjsch.Session;
import org.slf4j.Logger;

import java.io.*;
import java.util.concurrent.TimeUnit;

/**
 * @description: 最新版本SSHUtil
 * @author: wangjingshi
 * @create: 2021-09-03 09:50
 */
public class VgcBackupSshUtil {

    private String host = null;
    private String user = null;
    private String password = null;
    private Session session = null;
    private Logger log;
    private ChannelShell channel = null;
    private OutputStream out = null;
    private InputStream in =null;
    private String endStr = null;

    public VgcBackupSshUtil(String host, String user, String password, Logger log) {
        this.host = host;
        this.user = user;
        this.password = password;
        this.log = log;
    }

    public void connect() throws JSchException {
        Session openSession = null;
        JSch jsch = new JSch();
        openSession = jsch.getSession(user, host, 22);
        openSession.setPassword(password);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        openSession.setConfig(config);
        openSession.connect();
        this.session = openSession;
        System.out.println("ssh2 create connect success...");
    }

    public com.jcraft.enipjsch.ChannelShell getShellChannel() throws Exception{
        channel = (com.jcraft.enipjsch.ChannelShell) session.openChannel("shell");
        //channel.setPty(false);
        //channel.setPtyType("dumb");
        channel.setPtyType("dumb");
        channel.connect(30*1000);
        out = channel.getOutputStream();
        in = channel.getInputStream();
        return channel;
    }

    public com.jcraft.enipjsch.ChannelShell getShellChannelWithEnd() throws Exception{
        channel = (com.jcraft.enipjsch.ChannelShell) session.openChannel("shell");
        //channel.setPty(false);
        //channel.setPtyType("dumb");
        channel.setPtyType("dumb");
        channel.connect(30*1000);
        out = channel.getOutputStream();
        in = channel.getInputStream();

        endStr =getEndStr();
        return channel;
    }




    public void disconnect() {
        if (session != null && session.isConnected()) {
            session.disconnect();
            System.out.println("ssh2 session disconnect success...");
        }
    }

    public String sendCommand(String cmd, String end) throws Exception {
        PrintWriter printWriter = new PrintWriter(out);
        printWriter.println(cmd);
        printWriter.flush();
        return readUntil(end);
    }

    public String readUntil(String pattern) {
        try {
            char lastChar = pattern.charAt(pattern.length() - 1);
            StringBuffer sb = new StringBuffer();
            char ch = (char) in.read();
            while (true) {
                sb.append(ch);
                if (ch == lastChar) {
                    if (sb.toString().endsWith(pattern)) {
                        return sb.toString();
                    }
                }
                ch = (char) in.read();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String readUntil(String pattern,int count) throws Exception {
        int i =0;
        char lastChar = pattern.charAt(pattern.length() - 1);
        StringBuffer sb = new StringBuffer();
        BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
        char ch = (char) reader.read();
        while (true) {
            sb.append(ch);
            if (ch == lastChar) {
                i++;
                if (i==count && sb.toString().endsWith(pattern)) {
                    return sb.toString();
                }
            }
            ch = (char) reader.read();
        }
    }

    public String sendCommandV2(String cmd, String end,int count) throws Exception {
        System.out.println(cmd);
        out.write((cmd+" \n\r").getBytes("UTF-8"));
        out.flush();
        Thread.currentThread().sleep(2000l);
        return readUntil(end,count);
    }

    public String sendCommandV3(String cmd, String end) throws Exception {
        System.out.println(cmd);
        out.write((cmd+" \n\r").getBytes("UTF-8"));
        out.flush();
        Thread.currentThread().sleep(2000l);
        return readUntilV3(end,log);
    }

    public String sendCommandV3(String cmd, String end,int count) throws Exception {
        System.out.println(cmd);
        out.write((cmd+" \n\r").getBytes("UTF-8"));
        out.flush();
        Thread.currentThread().sleep(2000l);
        return readUntilV3(end,log,count);
    }

    public String readUntilV3(String pattern,Logger log) throws Exception {
        StringBuffer sb = new StringBuffer();
        BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
        String line = null;
        String result = null;
        int i = 0;
        while(true){
            line = reader.readLine();
            i++;
            if(i%10000==0){
                log.info(" ======= count:"+i);
            }
            result = result + line + "\r\n";
            if(line!=null&&line.contains(pattern)){
                log.info(" ======= result success:"+i);
                System.out.println("result success");
                //reader.close();
                return result;
            }
            if(i>=100000){
                //reader.close();
                return result;
            }
        }
    }

    public String readUntilV3(String pattern,Logger log,int count) throws Exception {
        StringBuffer sb = new StringBuffer();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
        String line = null;
        String result = null;
        int i = 0;
        while(true){
            line = reader.readLine();
            if(i%10000==0){
                log.info(" ======= count:"+i);
            }
            result = result + line + "\r\n";
            if(line!=null&&line.contains(pattern)){
                i++;
                if(i==count){
                    log.info(" ======= result success:"+i);
                    System.out.println("result success");
                    //reader.close();
                    return result;
                }
            }
            if(i>=100000){
                //reader.close();
                return result;
            }
        }
    }

    public String sendCommandV4(String cmd, String end,int count) throws Exception {
        System.out.println(cmd);
        out.write((cmd+"\n\r").getBytes("UTF-8"));
        out.flush();
        Thread.currentThread().sleep(2000l);
        return readUntil(end,count);
    }

    public String sendCommandV5(String cmd) throws Exception {
        System.out.println(cmd);
        out.write((cmd+" \n\r").getBytes("UTF-8"));
        out.flush();
        Thread.currentThread().sleep(2000l);
        return readUntilV5();
    }

    public String readUntilV5() throws Exception {
        boolean flag1 = false,flag2 = false;
        StringBuffer sb = new StringBuffer();
        BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
        char ch = (char) reader.read();
        int ich;
        while (true) {
            sb.append(ch);
            ich = (int)ch;
            if(ich==32&&flag1==false){
                flag1 = true;
                ch = (char) reader.read();
                continue;
            }
            if(ich==13&&flag2==false&&flag1==true){
                flag2 = true;
                ch = (char) reader.read();
                continue;
            }else if(ich==10&&flag1==true&&flag2==true){
                System.out.println("result success V5");
                return sb.toString();
            }else{
                flag1 = false;
                flag2 = false;
            }
            ch = (char) reader.read();
        }
    }

    public String readUntilV2(String pattern,int count) throws Exception {
        int i =0;
        char lastChar = pattern.charAt(pattern.length() - 1);
        StringBuffer sb = new StringBuffer();
        BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
        char ch = (char) reader.read();
        while (true) {
            sb.append(ch);
            if (ch == lastChar) {
                i++;
                if (i==count && sb.toString().endsWith(pattern)) {
                    return sb.toString();
                }
            }
            ch = (char) reader.read();
        }
    }


    public String sendCommands(String[] cmds) throws Exception {
        for(String cmd :cmds) {
            System.out.println(cmd);
            if(cmds[0].equals(cmd)){
                System.out.println("-----sleep 20000--------");
                TimeUnit.MILLISECONDS.sleep(20000);
            }else{
                System.out.println("-----sleep 5000--------");
                TimeUnit.MILLISECONDS.sleep(5000);
            }
            out.write((cmd + "\r\n").getBytes("UTF-8"));
            out.flush();
        }
        return readUtil();
    }

    public String readUtil() throws Exception {
        byte[] tmp=new byte[8192];
        StringBuilder sb = new StringBuilder();
        int a = 0;
        while(true){
            a++;
            while(in.available()>0){
                int i=in.read(tmp, 0, 1024);
                if(i<0)break;

                String s = new String(tmp, 0, i);
                if (s.indexOf("--More--") >= 0 ) {
                    out.write((" ").getBytes());
                    out.flush();
                }
                sb.append(new String(tmp, 0, i));
            }
            if(channel.isClosed()){
                if(in.available()>0) continue;
                break;
            }
            TimeUnit.MILLISECONDS.sleep(400);
        }
        return sb.toString();
    }

    public void onlySendCommand(String cmd) throws Exception {
        PrintWriter printWriter = new PrintWriter(out);
        printWriter.println(cmd);
        printWriter.flush();
    }


    private  String getEndStr() throws InterruptedException, IOException {

        Thread.sleep(1000);
        StringBuffer sb = new StringBuffer();
        while (in.available()>0){
            char ch = (char) in.read();
            sb.append(ch);
        }
        return sb.toString();
    }

    public String sendCommandByEnd(String cmd) throws Exception {
        out.write((cmd+" \n\r").getBytes("UTF-8"));
        out.flush();
        Thread.currentThread().sleep(1000l);
        return readUntilByend();
    }

    public String readUntilByend() throws Exception {

        StringBuffer sb = new StringBuffer();
        BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
        String line = reader.readLine();
        sb.append(line+"\r\n");
        while (true) {
            line = reader.readLine();
            if(line.endsWith(endStr)){
                break;
            }
            sb.append(line+"\r\n");
        }
        return sb.toString();
    }
}
